/**
 *  Serponix is an arcade game in focus to multiplayer based on the classic game Snake.
 *  Copyright (C) 2010 - 2011  Daniel Vala
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License,
 *  or  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  If you have any question do not hesitate to contact author
 *  on e-mail address: danielvala42@gmail.com
 */
package com.serponix.game.projectiles;

import com.serponix.game.Direction;
import com.serponix.game.GameModel;
import com.serponix.game.Snake;
import com.serponix.game.objektyNaPlose.Clanek;
import com.serponix.game.objektyNaPlose.VecNaPolicku;
import com.serponix.game.objektyNaPlose.ViceObjektu;
import com.serponix.game.objektyNaPlose.Zed;
import com.serponix.net.Informace;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

/**
 * Laser je druh střely, který při nárazu zaniká. Hadovi přitom ničí jeden článek.
 * Pokud laser zanikne, hadovi se opět naplní zásobník a může vystřelit další laser.
 * Laser může být smrtící, což znamená, že při nárazu hada resetuje.
 * Laser se může i odrazit. Po 3 odrazu ale zaniká.
 *
 * @author Daniel Vala
 */
public class Laser extends Projectile {

	private Color barva;
	private int poziceVZasobniku;
	private int pocetOdrazu;
	private boolean smrtici;

	public Laser(GameModel model, Snake had, int x, int y, Direction smer, int rychlost, int poziceVZasobniku, boolean smrtici) {
		super(model, had, x, y, smer, rychlost);
		this.poziceVZasobniku = poziceVZasobniku;
		this.smrtici = smrtici;
		if (smrtici) {
			barva = Color.GREEN;
		} else {
			this.barva = Color.RED;
		}
	}

	public boolean isSmrtici() {
		return smrtici;
	}

	/**
	 * Laser se odrazí, tzn. změní směr na směr opačný.
	 * // Laser vydrží jen 3 odrazy. Čtvrtý odraz laser zničí.
	 * TODO nutnost předělat kolize - zatím laser vydrží nekonečno odrazů
	 */
	public void odrazSe() {
		smer = Direction.obratSmer(smer);

		//        if (pocetOdrazu < 3) {
		//            smer = Smer.obratSmer(smer);
		//            pocetOdrazu++;
		//        } else {
		//            znicSe();
		//        }
	}

	/**
	 * Střela se odmapuje z herní plochy a nabije zásobník svému majiteli.
	 * Neodstraní se však ze seznamu střel v modelu.
	 */
	@Override
	public void znicSe() {
		snake.nabijZasobnik(poziceVZasobniku);
		odmapuj(model);
	}

	@Override
	protected boolean kolize(int x, int y) {
		if (checkBorderCollision(x, y)) {
			return true;
		}

		VecNaPolicku vecPredStrelou = model.getObjektNaHerniPlose(x, y);
		if (vecPredStrelou != null) {
			if (vecPredStrelou instanceof ViceObjektu) {
				ViceObjektu viceObjektu = (ViceObjektu) vecPredStrelou;
				for (VecNaPolicku vecNaPolicku : viceObjektu.getVeciNaPolicku()) {
					if (kolizeSObjektem(vecNaPolicku)) {
						return true;
					}
				}
				return false;
			} else {
				return kolizeSObjektem(vecPredStrelou);
			}
		}
		return false;
	}

	private boolean kolizeSObjektem(VecNaPolicku vecPredStrelou) {
		if (vecPredStrelou instanceof Clanek) {
			Clanek clanek = (Clanek) vecPredStrelou;
			if (clanek.getHad().zasah(this, clanek.getX(), clanek.getY())) {
				znicSe();
				return true;
			} else {
				return false; // pokud má had např. odolnost
			}
		} else if (vecPredStrelou instanceof Laser) {
			znicSe();
			//            Laser laser = (Laser) vecPredStrelou;
			//            laser.znicSeAOdstranSeZModelu();
			return true;
		} else if (vecPredStrelou instanceof Zed) {  // pokud střela narazila na stěnu mapy, zničí se
			znicSe();
			return true;
		} else {
			return false; // s jinými objekty kolize nevznikne
		}
	}

	private boolean checkBorderCollision(int x, int y) {
		if (model.isVHerniMape(x, y)) {
			return false;
		} else {
			znicSe();
			return true;
		}
	}

	public String getInstrukceProKresleni() {
		return Informace.LASER + Informace.ODDELOVAC3 + getX() + Informace.ODDELOVAC3 + getY() + Informace.ODDELOVAC3 + barva.getRGB() + Informace.ODDELOVAC3 + 0 + Informace.ODDELOVAC3 + Direction.prevedSmerNaCislo(smer) + Informace.ODDELOVAC2;
	}

	public static void paint(Graphics2D g2d, int x, int y, Direction smer) {
		x *= GameModel.getVelikostPolicka();
		y *= GameModel.getVelikostPolicka();

		if (smer == Direction.RIGHT || smer == Direction.LEFT) {
			g2d.fill3DRect(x + 2, y + 2, 25, 5, true);
		} else if (smer == Direction.UP || smer == Direction.DOWN) {
			g2d.fill3DRect(x + 2, y + 2, 5, 25, true);
		}
	}

	@Override
	public void draw(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.setPaint(barva);
		paint(g2d, getX(), getY(), smer);
	}
}
